/*  
 *  
 *  
 *  gh3ki
 */

package urnoted;

import java.awt.*;
import static java.awt.Color.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;

/** An instance represents a piano keyboard from C to C.
 */
public class KeyboardPanel extends JPanel{
    static final int WW=48, WH = 280;  // width and height of white keys
    static final int BW=28, BH = 184;  // width and height of black keys
    static final String LETTERS = "CDEFGABC";
    
    private int x, y;  // position (upper left corner coordinates) of keyboard
    private boolean showNames;  // whether to prints the names of the keys

    private Key wKeys[] = new Key[8];
    private Key bKeys[] = new Key[5];
    private NoteSynthesizer mSynth;
    private Key currKey = null;

    private Graphics2D g2;

    private Controller mController;
    
    public KeyboardPanel(int x, int y, boolean showNames, Controller controller) {
        Dimension mySize = new Dimension(400,300);
        this.setPreferredSize(mySize);
        mController = controller;
        this.mSynth = new NoteSynthesizer();

        this.x = x;
        this.y = y;
        int xIncrement = x;         //this.x was behaving "funkily"
        this.showNames = showNames;
        
        //Setup the white key array for later use
        for(int i = 0; i < wKeys.length; i++){
        	Note n = Note.values()[i];
        	n.setmPosition(Math.abs((i - 11)*15));
        	System.out.println(n.getmPosition());
            wKeys[i] = new Key(xIncrement,y,WW,WH,Note.values()[i],Color.WHITE,LETTERS.charAt(i));
            xIncrement += WW;
        }
        
        //Setup the black key array for later use
        xIncrement = this.x + WW - BW/2;
        bKeys[0] = new Key(xIncrement,y,BW,BH,Note.A5,Color.BLACK,'\0');
        xIncrement+=WW;
        bKeys[1] = new Key(xIncrement,y,BW,BH,Note.A5,Color.BLACK,'\0');
        xIncrement+=WW*2;
        for(int i = 2; i < bKeys.length; i++){
            bKeys[i] = new Key(xIncrement,y,BW,BH,Note.A5,Color.BLACK,'\0');
            xIncrement+=WW;
        }
        
        //Set mylistener to be both mouselistener and mousemotionlistener
        //(This permits both dragging and clicking)
        MyListener myListener = new MyListener();
        this.addMouseListener(myListener);
        this.addMouseMotionListener(myListener);
    }
    
    @Override
    public void paintComponent(Graphics g) {
    	System.out.println("KeyboardPanel paintcomponent called");
        g2 = (Graphics2D)g;
        g2.setFont(new Font("Arial Bold", Font.BOLD, 40));
        
        //Draw the white keys:
        for (int i = 0; i < wKeys.length; i++){
            g2.setColor(wKeys[i].getColor());
            g2.fill(wKeys[i].getKeyRect());
            g2.setColor(BLACK);
            g2.draw(wKeys[i].getKeyRect());
            if (showNames) {
                String label = "" + wKeys[i].getLetter();
                g2.drawString(label, this.x + WW*i + 11, y + WH - 10);
            }
        }
 
        // Draw the black keys:
        for(int i = 0; i < bKeys.length; i++){
            g2.setColor(bKeys[i].getColor());
            g2.fill(bKeys[i].getKeyRect());
            g2.setColor(BLACK);
            g2.draw(bKeys[i].getKeyRect());
        }
    }

    public void handleKey(Key keyIn){
        if(isNewKey(keyIn) && keyIn != null){
                clearKeys();
                if(this.mController.isCurrentNote(keyIn.getNote())){
                    keyIn.setColor(Color.GREEN);
                }else{
                   keyIn.setColor(Color.RED);
                }
                this.mController.keyPressed(keyIn.getNote());
                mSynth.playNote(keyIn.getNote());
        }
        currKey = keyIn;
    }
    
    public boolean isNewKey(Key keyIn){
        return !keyIn.equals(this.currKey);
    }
    
    public void clearKeys(){
        //Return keys to the non selected state
        for(int i = 0; i < bKeys.length; i++){
            bKeys[i].setColor(Color.BLACK);
        }
        for(int i = 0; i < wKeys.length; i++){
            wKeys[i].setColor(Color.WHITE);
        }
        //repaint();
    }
    
    class MyListener extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            //On mouse being pressed, check validity of key and color
            //appropriately
            //CHECK BLACK FIRST TO AVOID IMPACTING BOTH KEYS
            boolean set = false;
            for(int i = 0; i < bKeys.length; i++){
                if(bKeys[i].getKeyRect().contains(e.getPoint())){
                    handleKey(bKeys[i]);
                    set = true;
                }
            }
            if(!set){
                for(int i = 0; i < wKeys.length; i++){
                    if(wKeys[i].getKeyRect().contains(e.getPoint())){
                        handleKey(wKeys[i]);
                     }
                }
            }
            //repaint();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            //On mouse being "dragged" change which key is being highlighted
            //appropriately
            boolean set = false;

            for(int i = 0; i < bKeys.length; i++){
                if(bKeys[i].getKeyRect().contains(e.getPoint())){
                    handleKey(bKeys[i]);
                    set = true;
                }
            }
            if(!set){
                for(int i = 0; i < wKeys.length; i++){
                    if(wKeys[i].getKeyRect().contains(e.getPoint())){
                          handleKey(wKeys[i]);
                    }
                }
            }
            //repaint();
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            //Highlight keys to say which will be selected
            this.mouseReleased(e);
        }
        
        @Override
        public void mouseReleased(MouseEvent e) {
            //Return keys to the non selected state
            boolean set = false;
            clearKeys();
            for(int i = 0; i < bKeys.length; i++){
                if(bKeys[i].getKeyRect().contains(e.getPoint())){
                    bKeys[i].setColor(Color.DARK_GRAY);
                    set = true;
                }
            }
            for(int i = 0; i < wKeys.length; i++){
                if(!set && wKeys[i].getKeyRect().contains(e.getPoint())){
                    wKeys[i].setColor(Color.CYAN);
                }
            }
            //repaint();
            currKey = null;
        }
        
    }

    
}